<?php

namespace App\Model;


use Hyperf\Stringable\Str;

/**
 * @property bool $softDel 是否使用伪删除
 * @property array $adminPageListField 后台列表展示的字段
 * @property array $searchAllowEmpty 允许传空，即传入字段就进行筛选
 */
abstract class CrudModel extends Model
{

    protected bool $softDel = true;

    // 后台列表展示的字段
    protected array $adminPageListField = ['*'];


    // 允许 传空字符进行搜索的字段
    protected array $searchAllowEmpty = [

    ];

    /**
     * @param array $params1
     * @return \Hyperf\Database\Model\Builder
     */
    protected function autoSearch(array $params1 = [])
    {
        // 将空参数过滤掉
        $params = [];
        foreach ($params1 as $key=>$v){
            if (in_array($key, $this->searchAllowEmpty)) {
                $params[$key] = $v;
                continue;
            }
            // 空值都不进行筛选
            if (!empty($v)) {
                $params[$key] = $v;
            }
        }
        $where = [];
//        $id = $this->getKeyName();
//        if (!empty($params[$id])) {
//            $where[] = [$id, $params[$id]];
//        }
        if ($this->softDel) {
            $where[] = ['deleted_at', 0];
        }
        foreach ($params as $k => $v) {
            switch (true) {
                case Str::startsWith($k, 's_'):
                    // 模糊搜索的字段
                    $where[] = [Str::after($k, 's_'), 'like', "%{$v}%"];
                    break;
                case Str::endsWith($k, '_gte'):
                    // 大于等于
                    $where[] = [Str::beforeLast($k, '_gte'), '>=', $v];
                    break;
                case Str::endsWith($k, '_lte'):
                    // 小于等于
                    $where[] = [Str::beforeLast($k, '_lte'), '<=', $v];
                    break;
                default:
                    $where[] = [$k, $v];
                    break;
            }
        }
        return $this->where($where);
    }

    /**
     * @param array $params
     * @return \Hyperf\Database\Model\Builder;
     */
    public function buildQuery(array $params = [])
    {
        return $this->autoSearch($params);
    }

    abstract public function addOne(array $data);

    /**
     * @param $id
     * @param array $field
     * @return \Hyperf\Database\Model\Model|object|null|static
     */
    public function findById($id, array $field = ['*'])
    {
        return $this->buildQuery([
            $this->getKeyName() => $id,
        ])
            ->first($field);
    }

    abstract public function updateById($id, array $data);

    public function getSomeByIds($ids, $field = ['*'])
    {
        return $this->buildQuery()->whereIn($this->getKeyName(), $ids)->get($field);
    }

    /**
     * 以id为索引返回搜索结果
     * @param array $ids
     * @param array $field
     * @return array[]
     */
    public function getSomeByIdsIdxId($ids, $field = ['*'])
    {
        $lists = $this->getSomeByIds($ids, $field);
        if ($lists->isEmpty()) {
            return [];
        }
        return array_column($lists->toArray(), null, $this->getKeyName());
    }

    public function delByIds($ids)
    {
        if ($this->softDel) {
            $r = $this->buildQuery()
                ->whereIn($this->getKeyName(), $ids)
                ->update([
                    'deleted_at' => time(),
                ]);
        } else {
            $r = $this->buildQuery()
                ->whereIn($this->getKeyName(), $ids)
                ->delete();
        }
        return $r;
    }

    /**
     * @param array $params
     * @param int $page
     * @param int $ps
     * @return \Hyperf\Contract\LengthAwarePaginatorInterface
     */
    public function pageListForAdmin(array $params = [], $page = 1, $ps = 10)
    {
        return $this->pageListSort($this->buildQuery($params))->paginate($ps, $this->adminPageListField, 'page', $page);
    }

    /**
     * 后台分页列表的排序方式
     * @param \Hyperf\Database\Model\Builder $builder
     * @return \Hyperf\Database\Model\Builder;
     */
    protected function pageListSort($builder)
    {
        return $builder->orderByDesc($this->getKeyName());
    }

    /**
     * @param $params
     * @param $field
     * @return \Hyperf\Database\Model\Builder[]|\Hyperf\Database\Model\Collection|static[]
     */
    public function getAll($params = [], $field = ['*'])
    {
        return $this->getAllSort($this->buildQuery($params))->get($field);
    }

    /**
     * 获取所有的排序
     * @param \Hyperf\Database\Model\Builder $builder
     * @return \Hyperf\Database\Model\Builder;
     */
    protected function getAllSort($builder)
    {
        return $builder;
    }

    protected function updateField($params, $field, $value)
    {
        return $this->buildQuery($params)->update([$field=>$value,'updated_at'=>time()]);
    }

    /**
     * 插入时间戳
     * @param array $data
     * @return
     */
    protected function normalAddOne($data)
    {
        if ($this->softDel){
            $data['deleted_at'] = 0;
        }
        $data['created_at'] = $data['updated_at'] = time();
        return $this->insert($data);
    }

    protected function normalAddOneGetId($data)
    {
        if ($this->softDel){
            $data['deleted_at'] = 0;
        }
        $data['created_at'] = $data['updated_at'] = time();
        return $this->insertGetId($data);
    }
}